home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gekkan Dennou Club 147
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan).7z
/
Gekkan Dennou Club - 2000.8 Vol. 147 (Japan) (Track 1).bin
/
tools
/
zmc3v078
/
zmc3v078.lzh
/
SRCSV078.LZH
/
PARSESUB.C
< prev
next >
Wrap
C/C++ Source or Header
|
2000-03-28
|
35KB
|
1,532 lines
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "switch.h"
#include "makezmd.h"
#include "makezmd2.h"
#include "velo.h"
#include "etc.h"
#include "68lib.h"
/* #define MAXTRK (80 + 1) */ /* includes from makezmd.h */
/* #define MAXTRK (80) */
/* #define COMNTRKSIZE 8192 */
#include "structs.h"
#include "structs2.h"
void resetError(void);
inline LINEDATA *incrementLine(LINEDATA *ld);
UBYTE *skipComment(UBYTE *zms);
UBYTE *skipSpc(UBYTE *zms);
UBYTE *skipSpcCr(UBYTE *zms);
UBYTE *skipLine(UBYTE *zms);
int stricmp2(char *str1,const char *str2);
void zmserror(const char *errormes,int line,char *linebuf,char *zms,int warnlvl,int putzms);
UBYTE *getnum2(UBYTE *zms,DWORD *num,int *err);
UBYTE *getnum4(UBYTE *zms,DWORD *num,int *err,const char *spara[],int start);
UBYTE *setex(UBYTE *zmd, UBYTE *data, DWORD len, int mode);
UBYTE *txt2bin(UBYTE *zmd, UBYTE *zms,DWORD *zmsbyte);
UBYTE *exclusive(UBYTE *zmd, UBYTE *zms,UBYTE f0f7, DWORD *zmsskip,
const int ifno, const char *cmnt,
UBYTE roland,UBYTE dev,UBYTE mdl,
DWORD postlen, UBYTE *postdata,
char *leftbrace,char *rightbrace);
UBYTE *skiptochr(UBYTE *zms,const char *skip);
UBYTE *skipchr(UBYTE *zms,const char *skip);
UBYTE *getStep(UBYTE *zms, UWORD *step, UWORD Step,int *err,COMMONINF *cominf);
UBYTE *getpara(UBYTE *zms, VELOETCVAR v[], int *paras, const int mustover0);
UBYTE *getvpara(UBYTE *zms, VELOETCVAR **vp, int *paras);
UBYTE *get1AbsPara(UBYTE *zms,DWORD *para,DWORD rangefrom,DWORD rangeto,
char *outofrange,char *omitpara);
UBYTE *setTie(UBYTE *zms,TRKCHINF *trkdata,const int Trk,TRKINF *trkinf,
UBYTE note,UWORD *step, UWORD *gate, int relvelo, int omitgate,
UWORD Step,COMMONINF *cominf,WORD velo);
UBYTE *setTie2(UBYTE *zms,TRKCHINF *trkdata,const int Trk,TRKINF *trkinf,
UBYTE note,UWORD step, UWORD gate, int relvelo, int portchordflg,
WORD velo);
UBYTE *set98Tie(UBYTE *zms, UWORD *step, UWORD Step,COMMONINF *cominf, int *err);
UWORD getGate1(const int Trk,TRKINF *trkinf,UWORD Step);
UWORD getGate2(WORD qvar,BYTE qrel,UWORD Step, WORD gtreso);
void checkRenpu(TRKCHINF *trkdata, const int Trk,TRKINF *trkinf,int pflg);
UBYTE *makeRenpuStepGate(UBYTE *zms, const BYTE target[],TRKCHINF *trkdata,TRKINF *trkinf,
COMMONINF *cominf);
/* void makePortBresemhamPara(WORD br,WORD *add,WORD *cor,UWORD step); */
void setVelocitySequenceMode(TRKINF *trkinf,const BYTE trk,int mode);
inline void recoverSpecialVelocity(TRKINF *trkinf, int Trk);
UBYTE *checkOctaveChange(UBYTE *zms,TRKINF *trkinf,const int Trk);
void incrementStepCounters(TRKINF *trkinf, UWORD step);
int putZvar(UBYTE *zmd, DWORD var);
DWORD getZvar(UBYTE *zmd);
int putStepGate(UBYTE *zmd, RENP *r, UWORD step, UWORD gate);
void freeAllChord(CHKCHORD *c);
UBYTE *getChordGatePos(UBYTE *zmdbuf, DWORD gatepos, DWORD renpnotes);
extern DWORD line;
extern char *linebuf;
static char *zms__ = NULL;
extern char *infile;
extern LINEDATA *ld;
extern LINEFILEDATA *lfd;
void resetError(void)
{
zms__ = NULL;
}
inline LINEDATA *incrementLine(LINEDATA *ld)
{
if (ld->next) {
ld = ld->next;
}
return ld;
}
UBYTE *skipComment(UBYTE *zms)
{
while(*zms != 0x0d && *zms != 0x0a) {
/*
if (*zms == 0xff && *(zms + 1) == 0xff) {
break;
}
*/
zms++;
}
if (*zms == 0x0d && *(zms + 1) == 0x0a) {
zms += 2;
} else {
zms++;
}
linebuf = zms;
line++;
ld = incrementLine(ld);
return zms;
}
UBYTE *skipSpc(UBYTE *zms)
{
const unsigned char *sp2 = " "; /* Japanese specified WIDE SPACE character */
while (*zms == ' ' || *zms == '\t' || *zms == '/' ||
(*zms == *sp2 && *(zms + 1) == sp2[1]) ) {
if (*zms == '/') {
zms = skipComment(zms);
} else if (*zms == *sp2) {
if (*(zms + 1) == sp2[1]) {
zms += 2;
}
} else {
zms++;
}
}
return zms;
}
/* ================================
skip "space" and "return"
================================ */
UBYTE *skipSpcCr(UBYTE *zms)
{
const unsigned char *sp2 = " ";
while (1) {
switch (*zms) {
case 0xff:
if (*(zms + 1) == 0xff) {
goto EXITSKIPSPCCRLOOP;
}
break;
case 0x0d:
if (*(zms + 1) == 0x0a) {
/* zms += 2; */
zms++;
}
/* NO BREAK */
case 0x0a:
linebuf = ++zms;
line++;
ld = incrementLine(ld);
break;
case '/':
zms = skipComment(zms);
break;
case ' ':
case '\t':
zms++;
break;
default:
if (*zms == sp2[0] && *(zms + 1) == sp2[1]) {
zms += 2;
break;
}
goto EXITSKIPSPCCRLOOP;
/* break; */
}
}
EXITSKIPSPCCRLOOP:
return zms;
}
/* =================
skip the line
================== */
UBYTE *skipLine(UBYTE *zms)
{
while (1) {
switch (*zms) {
case 0xff:
if (*(zms + 1) == 0xff) {
goto EXITSKIPSPCCRLOOP;
}
break;
case 0x0d:
if (*(zms + 1) == 0x0a) {
/* zms += 2; */
zms++;
}
/* NO BREAK */
case 0x0a:
linebuf = ++zms;
line++;
ld = incrementLine(ld);
goto EXITSKIPSPCCRLOOP;
break;
default:
zms++;
break;
}
}
EXITSKIPSPCCRLOOP:
return zms;
}
/* ======================================================
strings compare, (it must be strlen(str1) >= strlen(str2) )
====================================================== */
int stricmp2(char *str1,const char *str2)
{
/* const int len1 = strlen(str1); */
const int len2 = strlen(str2);
/* char s1[1024]; */
char tmp;
int rc;
/* s1 = (char*)emalloc(sizeof(char) * len1 + 1); */
/*
strncpy(s1,str1,len2);
s1[len2] = '\0';
*/
tmp = str1[len2];
str1[len2] = '\0';
rc = stricmp(str1,str2); /* caseless strings compare */
/* efree(s1); */
str1[len2] = tmp;
return rc;
}
/* =========
ERROR
warnlvl: 0=err 1- warn level
========= */
void zmserror(const char *errormes,int line,char *linebuf,char *zms,int warnlvl,int putzms)
{
char *str, *p = linebuf;
int i,len,len2 = zms - linebuf;
while (*p != 0x0d && *p != 0x0a && *p != 0x1a && *p != (char)-1) {
p++;
}
/* p = skipComment(linebuf); */
len = p - linebuf; /* len: length of zmsline */
if (!getSwitchVal('w') || (zms__ != zms && getSwitchVal('w') >= warnlvl)) {
char *p,*em;
em = emalloc(sizeof(char) * (strlen(errormes) + 16),"em");
if (warnlvl) {
strcpy(em,"Warning: ");
} else {
strcpy(em,"Error: ");
}
strcat(em,errormes);
zms__ = zms;
str = emalloc(sizeof(char) * (len + 1),"str_in_zmserror");
if (len) {
strncpy(str,linebuf,len);
}
str[len] = '\0';
p = str - 1;
while (*++p) {
if (*p == 0x1a) {
*p = '\0';
}
}
if (getSwitchVal('l') != SET_VAL) {
/* fprintf(stderr,"%s\t%d: %s\n",infile,line,em); */
fprintf(stderr,"%s\t%d: %s\n", ld->filename, ld->line, em);
} else {
/* fprintf(stderr,"%s\tL%dC%d: %s\n",infile,line,len2 + 1,em); */
fprintf(stderr,"%s\tL%dC%d: %s\n", ld->filename, ld->line, len2 + 1, em);
}
if (putzms) {
fprintf(stderr,"%s\n",str);
for (i = 0; i < len2; i++) {
if (str[i] == '\t') {
fprintf(stderr,"\t");
} else {
fprintf(stderr," ");
}
}
fprintf(stderr,"^\n");
}
efree(str,"str");
efree(em,"em");
if (!warnlvl) {
exit(1);
}
}
}
/* =======================================
text->numeric conversion
$xx , %xxxx are OK,too
*err= 0: no err
1: SYNTAX ERR
-1: no value
======================================== */
UBYTE *getnum2(UBYTE *zms,DWORD *num,int *err)
{
BYTE sign = 1;
BYTE binhex = 10;
BYTE novalue = 1;
*num = *err = 0;
zms = skipSpcCr(zms);
for (;;) {
switch (*zms) {
case '+':
if (novalue) {
zms++;
} else {
goto SWLOOPEND;
}
break;
case '-':
if (novalue) {
sign = -1;
zms++;
} else {
goto SWLOOPEND;
}
break;
case '%':
binhex = 2;
zms++;
break;
case '$':
binhex = 16;
zms++;
break;
case '0': case '1':
case '2': case '3':
case '4': case '5':
case '6': case '7':
case '8': case '9':
if (binhex == 2 && *zms >= '2') {
*err = 1;
goto SWLOOPEND;
}
*num *= binhex;
*num += *zms++ - '0';
novalue = 0;
break;
case 'a': case 'A':
case 'b': case 'B':
case 'c': case 'C':
case 'd': case 'D':
case 'e': case 'E':
case 'f': case 'F':
/* *zms |= 0x20; */
if (binhex != 16) { /* e.g.: c1a */
/* *err = 1; */
goto SWLOOPEND;
}
*num *= 16;
*num += tolower(*zms++) - 'a' + 10;
novalue = 0;
break;
case ' ':
case '\t':
if (novalue) {
zms++ ;
zmserror("illegal space.",line,linebuf,zms,3,1);
break ;
}
default:
goto SWLOOPEND;
/* break; */
}
}
SWLOOPEND:
if (novalue) {
if (sign == -1 || binhex != 10) {
*err = 1;
} else {
*err = -1;
}
}
*num *= sign;
/* printf("[%d %d]",*num,*err); */
return zms;
}
UBYTE *getnum4(UBYTE *zms,DWORD *num,int *err,const char *spara[], int start)
{
int p = 0 - 1;
zms = skipSpc(zms);
*err = -1;
while (spara[++p]) {
if (!stricmp2(zms, spara[p])) {
*num = p + start;
*err = 0;
zms += strlen(spara[p]);
break;
}
}
if (*err < 0) {
zms = getnum2(zms,num,err);
if (*err > 0) {
zmserror("parameter error.",line,linebuf,zms,0,1);
}
}
return zms;
}
/* ===========================================================
exclusive(low level)
put "data"s simply. ("len" bytes)
put Roland/YAMAHA Exclusive additionaly (if "mode" is set.)
mode=1: Roland
mode=2: YAMAHA
mode=4: YAMAHA(DX)
=========================================================== */
UBYTE *setex(UBYTE *zmd, UBYTE *data, DWORD len, int mode)
{
DWORD i;
UBYTE sum = 0;
if (mode == 1 || mode == 2 || mode == 4) { /* with Roland/YAMAHA checksum */
const DWORD exceptsum = (mode == 1)? 5 : 4;
for (i = 0; i < exceptsum; i++) { /* ID,dev,etc.. */
*zmd++ = *data++;
}
if (mode == 2 || mode == 4) { /* for YAMAHA: add block size */
DWORD bytecount = len - exceptsum;
if (mode == 2) {
bytecount -= 3; /* for address */
}
/* putWord(zmd, len - exceptsum - 3); */
*zmd = (bytecount >> 7) & 0x7F;
if (mode == 2) {
sum -= *zmd++;
} else {
zmd++;
}
*zmd = bytecount & 0x7F;
if (mode == 2) {
sum -= *zmd++;
} else {
zmd++;
}
}
for (i = exceptsum; i < len; i++) {
*zmd++ = *data;
sum -= *data++;
}
*zmd++ = sum & 0x7f;
} else {
for (i = 0; i < len; i++) {
*zmd++ = *data++;
}
}
return zmd;
}
/* ========================================
text->binary conversion
"strings" supports.
week point: poor error check
======================================== */
UBYTE *txt2bin(UBYTE *zmd, UBYTE *zms, DWORD *zmsbyte)
{
UBYTE *zms_ = zms;
DWORD bytes;
int err;
DWORD num;
zms = getnum2(zms,&num,&err);
/* printf("(%d %d)",num,err); */
bytes = zms - zms_;
if (err < 0 && *zms == '\"') { /* "strings" */
zms++;
bytes++;
while (*zms != '\"' && *zms != '\n') {
*zmd++ = *zms++;
bytes++;
if (*zms == 0xff && *(zms + 1) == 0xff) {
break;
}
}
/* zms++; */ /* no need */
bytes++;
} else if (!err) { /* numerics */
if (num >= 256) {
do {
*zmd++ = num & 0x7f;
num >>= 7;
} while (num);
} else {
*zmd++ = num;
}
} else if (*zms == ',') {
/* bytes = -1; */
}
*zmsbyte = bytes;
return zmd;
}
UBYTE *exclusive(UBYTE *zmd, UBYTE *zms,UBYTE f0f7, DWORD *zmsskip,
const int ifno, const char *cmnt,
UBYTE roland,UBYTE dev,UBYTE mdl,
DWORD postlen, UBYTE *postdata,
char *leftbrace,char *rightbrace)
{
/* roland == 0:no vendor infomation
1:Roland
2:YAMAHA w/ sum
3:YAMAHA w/o sum
4:DX (w/ sum, sum doesn't include bytecount)
*/
int len,len2;
DWORD zmsbyte = 0;
UBYTE *data = (UBYTE*)emalloc(sizeof(UBYTE) * 8192, "data_in_exclusive");
UBYTE *data_ = data;
UBYTE *zms_ = zms;
int lbflg = 0;
if (f0f7) {
*data++ = 0xf0;
}
if (roland == 1) {
*data++ = 0x41; /* Roland maker ID */
*data++ = dev;
*data++ = mdl;
*data++ = 0x12;
} else if (roland == 2 || roland == 3 || roland == 4) {
*data++ = 0x43; /* YAMAHA maker ID */
*data++ = dev;
*data++ = mdl;
}
if (postlen) {
for (len = 0; len < postlen; len++) {
*data++ = *postdata++;
}
}
if (*leftbrace) {
#ifdef __GNUC__
char skip[2] = { *leftbrace, '\0' };
#else
char skip[2] = { '\0','\0' };
skip[0] = *leftbrace;
#endif
zms = skiptochr(zms,skip);
if (!zms || *zms == 0xFF) {
zmserror("unexpected EOF.",line,linebuf,zms,0,1);
} else if (*zms++ != *leftbrace) {
char str[128];
sprintf(str,"`%s' not found.",*leftbrace);
zmserror(str,line,linebuf,zms,0,1);
}
} else {
zms = skipSpcCr(zms);
}
if (*leftbrace == '\"') {
zms--;
lbflg = 1;
}
while (*zms != rightbrace[0] || lbflg) {
lbflg = 0;
data = txt2bin(data,zms,&zmsbyte);
if (zmsbyte >= 0) { /* if not ',' */
zms += zmsbyte;
if (*leftbrace == '\"' && strlen(leftbrace) == 1) {
/* only "..." strings is allowed ... .sc55_print etc.*/
zms--;
}
}
/*printf("%c",*zms); */
if (*zms == '/') {
zms = skipComment(zms);
}
if (!strchr(rightbrace, *zms)) {
/* char str[128]; */
/* sprintf(str,"%.2x: illegal partion character.",*zms); */
zmserror("illegal partition character.",line,linebuf,zms,0,1);
}
if (*zms == ',') { /* if ',' */
zms++;
} else if (*zms == 0xFF && *(zms + 1) == 0xFF) { /* EOF */
zmserror("unexpected EOF.",line,linebuf,zms,0,1);
}
if (*leftbrace == '\"') {
break;
}
}
*zmd++ = 0x34; /* MIDI DATA transfer */
*zmd++ = ifno; /* IF number: (-1 == current IF) */
if (cmnt) {
*zmd++ = strlen(cmnt); /* comment length */
strcpy(zmd, cmnt);
zmd += strlen(cmnt);
} else {
*zmd++ = 0;
}
len2 = len = data - data_;
if (f0f7) {
len2++; /* len + 1:for 0xF7 */
}
if (roland == 1) {
len2++; /* for checksum */
} else if (roland == 2) {
len2 += 3; /* for ByteCount(2) + checksum(1) */
} else if (roland == 4) {
len2 += 3; /* for ByteCount(2) + checksum(1) */
}
putDword(zmd, len2);
zmd += 4;
zmd = setex(zmd, data_, len, roland);
if (f0f7) {
*zmd++ = 0xf7;
}
efree(data_,"data_");
*zmsskip = zms - zms_ + 1;
return zmd;
}
/* ==========================
scan texts "until" skip_characters comes.
if feof, return NULL.(means ERROR)
========================== */
UBYTE *skiptochr(UBYTE *zms,const char *skip)
{
while ( *zms != 0xFF && !strchr(skip, *zms) ) {
if (*zms == 0x0d) {
if (*(zms + 1) == 0x0a) {
zms += 2;
} else {
zms++;
}
linebuf = zms;
line++;
ld = incrementLine(ld);
} else if (*zms == 0x0a) {
linebuf = ++zms;
line++;
ld = incrementLine(ld);
} else {
zms++;
}
}
if (*zms == 0xFF && *(zms + 1) == 0xFF) {
return NULL;
} else {
return zms;
}
}
/* ==========================
scan texts "while" skip_characters comes.
if feof, return NULL.(means ERROR)
========================== */
UBYTE *skipchr(UBYTE *zms,const char *skip)
{
while ( *zms != 0xFF && strchr(skip, *zms) ) {
if (*zms == 0x0d) {
if (*(zms + 1) == 0x0a) {
zms += 2;
} else {
zms++;
}
linebuf = zms;
line++;
ld = incrementLine(ld);
} else if (*zms == 0x0a) {
linebuf = ++zms;
line++;
ld = incrementLine(ld);
} else {
zms++;
}
}
if (*zms == 0xFF && *(zms + 1) == 0xFF) {
return NULL;
} else {
return zms;
}
}
UBYTE *getStep(UBYTE *zms, UWORD *step, UWORD Step,int *err_,COMMONINF *cominf)
{
UWORD step_ = 0;
int err;
DWORD para;
*err_ = 0;
zms = getnum2(zms,¶,&err); /* step parameter */
if (!err) {
step_ = (para)? cominf->div / para : 0;
/* quaternote etc.. (not set ticks directly) */
} else if (err < 0) {
if (*zms == '*') { /* set ticks directry */
zms = getnum2(++zms,¶,&err);
if (err) {
zmserror("`*' must be followed to its parameter.",line,linebuf,zms,0,1);
}
step_ = para;
} else { /* no parameters */
step_ = Step;
*err_ = 2;
}
} else {
zmserror("SYNTAX ERROR",line,linebuf,zms,0,1);
}
para = step_; /* "."(dots) */
while (*zms == '.') {
para /= 2;
step_ += para;
zms = skipSpc(++zms);
*err_ = 1;
}
*step = step_;
return zms;
}
/* ===========================
get parameter (1/8 series)
=========================== */
UBYTE *getpara(UBYTE *zms, VELOETCVAR v[], int *paras, const int mustover0)
{
DWORD velo = 127,znum = 0;
int i,err;
zms--;
do {
BYTE rel;
int znumadd = 0;
for (i = 0; i < 2; i++) { /* i== 0:velo 1:randompara */
zms = skipSpcCr(zms + 1);
/* if (i != 0 && (*zms == '+' || *zms == '-')) { */
if (*zms == '+' || *zms == '-') {
rel = 1;
} else {
rel = 0;
}
zms = getnum2(zms,&velo,&err);
if (err < 0) { /* omit 1st/Xth parameter */
if (znum != 0) {
v[znum].var[i] = v[znum - 1].var[i];
}
v[znum].relflg[i] = 2; /* set "omit-flg" */
if (*zms == ',' /*|| *zms == ':'*/) { /* continue.. */
znumadd = 1;
/* v[0].var[i] = 0; */
/* v[znum].relflg[i] = 2; */ /* set "omit-flg" */
/* znum = 1; */
} else { /* that's all */
/* printf("[V=%d]",velo); */
/* znum = 0; */
}
} else { /* there is 1st/Xth parameter */
if (mustover0 && !velo) {
zmserror("This parameter must be over 0.",line,linebuf,zms,0,1);
}
v[znum].var[i] = velo;
v[znum].relflg[i] = rel;
znumadd = 1;
}
/* printf("[V=%d]",velo); */
zms = skipSpcCr(zms);
if (*zms != ':' || (*zms == ':' && *(zms + 1) == '|')) {
int j;
for (j = i + 1; j < 2; j++) {
v[znum].var[j] = 0;
v[znum].relflg[j] = -1;
}
break;
}
}
znum += znumadd;
} while (*zms == ',');
*paras = znum;
if (znum > 0 && v[znum - 1].relflg[0] == 2) { /* if the last parameter is omitted */
(*paras)--;
}
return zms;
}
/* ===========================
get variable length parameter
=========================== */
UBYTE *getvpara(UBYTE *zms, VELOETCVAR **vp, int *paras)
{
DWORD znum = 0;
DWORD znummax = 8;
*vp = emalloc(sizeof(VELOETCVAR) * znummax,"vp_in_getvpara");
zms--;
do {
DWORD var;
int i,err;
BYTE rel;
for (i = 0; i < 2; i++) {
(*vp)[znum].var[i] = 0;
(*vp)[znum].relflg[i] = -1;
}
for (i = 0; i < 2; i++) {
zms = skipSpcCr(zms + 1);
if (*zms == '*') {
zms++;
rel = 3;
} else {
rel = (*zms == '+' || *zms == '-') ? 1 : 0;
}
zms = getnum2(zms,&var,&err);
if (err) { /* omit 1st/Xth parameter */
var = (znum > 0) ? (*vp)[znum - 1].var[0] : 0;
rel = 2; /* set "omit-flg" */
}
(*vp)[znum].var[i] = var;
(*vp)[znum].relflg[i] = rel;
zms = skipSpcCr(zms);
if (*zms != ':' || *(zms + 1) == '|') break;
}
if (++znum == znummax) {
znummax += 8;
*vp = erealloc(*vp, sizeof(VELOETCVAR) * znummax,"vp_in_getvpara");
}
zms = skipSpcCr(zms);
} while (*zms == ',');
/* *vp = erealloc(*vp, sizeof(VELOETCVAR) * znum); */
if ((*vp)[znum - 1].relflg[0] == 2) { /* if the last parameter is omitted */
znum--;
}
*paras = znum;
return zms;
}
/* ==============================
get parameter(can't omit parameter, cant set parameter relatively)
============================== */
UBYTE *get1AbsPara(UBYTE *zms,DWORD *para,DWORD rangefrom,DWORD rangeto,
char *outofrange,char *omitpara)
{
UBYTE *zms_ = zms;
DWORD line_ = line;
UBYTE *linebuf_ = linebuf;
/* LINEDATA *ld_ = ld; */
int err;
zms = getnum2(zms,para,&err);
if (!err) {
if (rangefrom != rangeto && (*para < rangefrom || rangeto < *para)) {
zmserror(outofrange,line_,linebuf_,zms_,0,1);
}
} else {
zmserror(omitpara,line_,linebuf_,zms_,0,1);
}
return zms;
}
UBYTE *setTie(UBYTE *zms,TRKCHINF *trkdata,const int Trk,TRKINF *trkinf,
UBYTE note,UWORD *step, UWORD *gate, int relvelo, int omitgate,
UWORD Step,COMMONINF *cominf, WORD velo)
{
int err;
zms = skipSpcCr(zms);
zms = set98Tie(zms, step, Step, cominf, &err);
if ((omitgate == 2 && *gate != 0x8000) || err != 2) { /* add v0.70: 0x8000 */
*gate = getGate1(Trk,trkinf,*step);
}
{ /* add v0.72 */
UWORD bakgate = *gate;
int err;
VELOETCVAR v;
BYTE relvelo;
v.var[0] = 0;
v.relflg[0] = 2;
/* gate */
zms = getGate(zms,Trk,trkinf,*step,gate,&err,cominf);
if (err == 2) {
*gate = bakgate;
}
/* zms = checkOctaveChange(zms,trkinf,Trk); */
/* velo */
zms = getSpecialVelocity(zms,&v);
setVelo0(trkdata,Trk,v,&relvelo,trkinf,cominf,*step);
}
zms = skipSpcCr(zms);
if (*zms == '&') { /* tie */
*gate = 0x8000;
zms++;
}
zms = setTie2(zms,trkdata,Trk,trkinf,
note,*step,*gate,relvelo,0,velo);
return zms;
}
UBYTE *setTie2(UBYTE *zms,TRKCHINF *trkdata,const int Trk,TRKINF *trkinf,
UBYTE note,UWORD step, UWORD gate, int relvelo, int portchordflg,
WORD velo)
{
/* printf("[note,sgv,tie=%d,%d,%d,%d,%d]",note,step,*gate,velo,tie); */
if (step == 0 && note != 0x80 && gate == 0) { /* *0 */
/* && gate <= 1 */
*trkdata[Trk].zmd++ = 0xB2;
*trkdata[Trk].zmd++ = note;
/* *data++ = note; */
if (relvelo == 0) { /* default velo */
*trkdata[Trk].zmd++ = 128;
} else if (relvelo > 0) { /* relative velo */
if (abs(velo) > 63) {
zmserror("relative velocity must be in from -63 to 63.",line,linebuf,zms,0,1);
}
*trkdata[Trk].zmd++ = 192 + velo;
} else { /* special velo */
int v = velo + trkinf[Trk].veloofst;
if (v > 127) {
v = 127;
} else if (v < 0) {
v = 0;
}
*trkdata[Trk].zmd++ = v;
}
} else {
*trkdata[Trk].zmd++ = note;
if (trkinf[Trk].renpnotes) {
checkRenpu(trkdata,Trk,trkinf,portchordflg);
}
trkdata[Trk].zmd += putStepGate(trkdata[Trk].zmd, trkinf[Trk].r->prev,step,gate);
#ifdef A
if (trkinf[Trk].r->prev) { /* always 2byte while renpu */
putWord(trkdata[Trk].zmd, step);
putWord(trkdata[Trk].zmd + 2, gate);
trkdata[Trk].zmd += 4;
} else {
trkdata[Trk].zmd += putZvar(trkdata[Trk].zmd, step);
trkdata[Trk].zmd += putZvar(trkdata[Trk].zmd, gate);
}
#endif
if (note != 0x80) {
if (relvelo == 0) { /* default velo */
*trkdata[Trk].zmd++ = 128;
} else if (relvelo > 0) { /* relative velo */
if (abs(velo) > 63) {
zmserror("relative velocity must be in from -63 to 63.",line,linebuf,zms,0,1);
}
*trkdata[Trk].zmd++ = 192 + velo;
} else { /* special velo */
int v = velo + trkinf[Trk].veloofst;
if (v > 127) {
v = 127;
} else if (v < 0) {
v = 0;
}
*trkdata[Trk].zmd++ = v;
}
}
if (relvelo) {
trkinf[Trk].spvelomode = 1;
/* *trkdata[Trk].zmd++ = 0x84; */ /* recover special velocity */
}
}
/* printf("[%d]",data - data_); */
/* *data2 = data; */
return zms;
}
UBYTE *set98Tie(UBYTE *zms, UWORD *step, UWORD Step,COMMONINF *cominf, int *err)
{
*err = 2; /* 2: no parameter 0: there is parameter */
while (*zms == '^') { /* 98 tie */
UWORD addstep;
int err_;
zms = getStep(++zms, &addstep, Step, &err_,cominf);
if (err_ != 2) {
*err = 0;
}
*step += addstep;
zms = skipSpcCr(zms);
}
return zms;
}
/* ======================================
get gate without numeric parameter
====================================== */
UWORD getGate1(const int Trk,TRKINF *trkinf,UWORD Step)
{
/* const int Trk = target[Trk]; */
BYTE *qpos = &(trkinf[Trk].quantizepos);
WORD qvar = trkinf[Trk].quantize[*qpos].var[0];
BYTE qrel = trkinf[Trk].quantize[*qpos].relflg[0];
return getGate2(qvar,qrel,Step, trkinf[Trk].gtreso);
}
UWORD getGate2(WORD qvar,BYTE qrel,UWORD Step, WORD gtreso)
{
UWORD gate;
if (qrel == 1) {
if (qvar < 0 || Step > qvar) {
gate = Step - qvar;
} else {
gate = Step;
}
} else if (qrel == 3) {
if (Step < qvar) {
gate = Step;
} else {
gate = qvar;
}
} else {
gate = Step * qvar / gtreso;
if (gate == 0 && Step != 0) {
gate = 1;
}
}
return gate;
}
void checkRenpu(TRKCHINF *trkdata, const int Trk,TRKINF *trkinf,int pflg)
{
/* const int Trk = target[Trk]; */
if (trkinf[Trk].renpnotes) { /* renpu? */
BYTE *qpos = &(trkinf[Trk].quantizepos);
char s[32];
sprintf(s,"trkinf[%d].r->next");
trkinf[Trk].renpnotes++;
trkinf[Trk].r->step = trkdata[Trk].zmd - trkdata[Trk].zmdbuf;
trkinf[Trk].r->qvar = trkinf[Trk].quantize[*qpos].var[0];
trkinf[Trk].r->qrelflg = trkinf[Trk].quantize[*qpos].relflg[0];
trkinf[Trk].r->pflg = pflg; /* ==1: portament */
/* ==2: chord */
trkinf[Trk].r->next = (RENP*)emalloc(sizeof(RENP) * 1,s);
trkinf[Trk].r->next->prev = trkinf[Trk].r;
trkinf[Trk].r = trkinf[Trk].r->next;
trkinf[Trk].r->next = NULL;
}
}
UBYTE *makeRenpuStepGate(UBYTE *zms, const BYTE target[],TRKCHINF *trkdata,TRKINF *trkinf,
COMMONINF *cominf)
{
int trk;
UBYTE *zms_ = zms;
int warnoct = 0;
for (trk = 0; target[trk] >= 0; trk++) {
const int Trk = target[trk];
const int beforeOctave = trkinf[Trk].octave;
UWORD step, step1,stepincs;
DWORD i;
DWORD ofst = 0;
int lastchord = 1; /* last chord */
int err;
BYTE tieflag = 0; /* become 1 when {..}nn& */
DWORD renpnotes = 0; /* renp notes (chord should be counted as 1 note) */
if (trkinf[Trk].r->prev == NULL) {
if (cominf->trackmode) {
cominf->trackmode = 0;
return zms; /* for .track ... { ... } */
} else if (trkinf[Trk].renpnotes == 1) {
trkinf[Trk].renpnotes = 0;
return zms; /* for the data {} (NULL renpu) */
} else {
zmserror("no { found..",line,linebuf,zms,0,1);
}
}
zms = getStep(zms_, &step, trkinf[Trk].Step,&err,cominf);
zms = skipSpcCr(zms);
zms = checkOctaveChange(zms,trkinf,Trk);
zms = skipSpcCr(zms);
zms = set98Tie(zms,&step,trkinf[Trk].Step,cominf,&err);
zms = skipSpcCr(zms);
trkinf[Trk].total += step;
if (*zms == '&') {
tieflag = 1;
zms++;
}
if (tieflag && beforeOctave != trkinf[Trk].octave && !warnoct) {
zmserror("There is octave switch(es) between NOTE and TIE.",line,linebuf,zms,3,1);
warnoct = 1;
}
{
RENP *r = trkinf[Trk].r;
int i;
for (i = trkinf[Trk].renpnotes - 1; i > 0; i--) {
r = r->prev;
if (r->pflg != 2) {
renpnotes++;
}
}
}
/* ERROR handle is needed: for the case renpnotes == 0 */
step1 = step / renpnotes;
stepincs = step % renpnotes;
incrementStepCounters(&trkinf[Trk],step);
#ifdef AAA
if (trkinf[Trk].s->prev) {
trkinf[Trk].s->step += step;
}
#endif
for (i = trkinf[Trk].renpnotes - 1; i > 0; i--) {
UWORD step_ = step1;
UWORD step0 = step1;
/* UWORD stepold; */
UWORD gateold;
UBYTE *RenpuStepPos;
UBYTE note;
int delta;
UWORD delay;
if ( i < trkinf[Trk].renpnotes - 1 && trkinf[Trk].r->pflg) {
lastchord = 0;
}
trkinf[Trk].r = trkinf[Trk].r->prev;
RenpuStepPos = trkdata[Trk].zmdbuf + trkinf[Trk].r->step;
note = *(RenpuStepPos - 1);
efree(trkinf[Trk].r->next,"trkinf[Trk].r->next");
delay = getWord(RenpuStepPos); /* for chord */
if (i <= stepincs) {
step_++;
step0++;
}
#ifdef A
stepold = getWord(RenpuStepPos);
if (cominf->renpmode == 1 && trkinf[Trk].r->pflg == 0) {
*RenpuStepPos = step_;
} else {
putWord(RenpuStepPos, step_);
}
#endif
/* fprintf(stderr,"pflg==%d",trkinf[Trk].r->pflg); */
if (trkinf[Trk].r->pflg == 2) {
/* chord, but isn't the last note */
step_ = delay; /* getWord(RenpuStepPos); */
/* fprintf(stderr,"(d=%d)",delay); */
}
delta = putZvar(RenpuStepPos, step_);
/* fprintf(stderr,"[%d/",step_); */
#ifdef A
if (trkinf[Trk].r->pflg == 1) { /* portament */
WORD br = 0,add,cor,cor0 = 0;
UWORD j, delayold;
delayold = getWord(RenpuStepPos + 4);
add = getWord(RenpuStepPos + 6); /* get bend range */
cor = *(RenpuStepPos + 8);
for (j = 0; j < stepold - delayold; j++) {
br += add;
cor0 += cor;
if (cor0 > 0xFF) {
br++;
cor0 -= 0x100;
}
}
step_ -= delayold; /* make new add/cor */
/* br = (note[1] - note[0]) * 683; */ /* bend range */
makePortBresemhamPara(br,&add,&cor,step_);
putWord(RenpuStepPos + 6, add); /* set new add/cor */
*(RenpuStepPos + 8) = cor & 0xFF;
}
#endif
#ifdef A
if (cominf->renpmode == 1 && trkinf[Trk].r->pflg == 0) {
gateold = *(RenpuStepPos + 1);
if (gateold == 0xFF) {
gateold = 0x8000;
}
} else {
gateold = getWord(RenpuStepPos + 2);
}
#endif
/* gateold = getZvar(RenpuStepPos + 2); */
gateold = getWord(RenpuStepPos + 2);
/* fprintf(stderr,"(%.2x)/",gateold); */
if (i == trkinf[Trk].renpnotes - 1 && tieflag) { /* {..}nn& */
gateold = 0x8000;
#ifdef A
if (cominf->renpmode == 1 && trkinf[Trk].r->pflg == 0) {
*(RenpuStepPos + 1) = gateold;
} else {
putWord(RenpuStepPos + 2, gateold);
}
#endif
/*
putZvar(RenpuStepPos + delta, 0x8000);
*/
}
/*
delayを含む和音のgate値の再計算はどうする?
*/
if (gateold != 0x8000) { /* not TIE */
WORD qvar = trkinf[Trk].r->qvar;
BYTE qrel = trkinf[Trk].r->qrelflg;
/* UWORD gate; */
if (trkinf[Trk].r->pflg == 2) { /* chord */
step_ = step0 - delay;
}
gateold = getGate2(qvar,qrel,step_,trkinf[Trk].gtreso);
#ifdef A
if (cominf->renpmode == 1 && trkinf[Trk].r->pflg == 0) {
*(RenpuStepPos + 1) = gate;
} else {
putWord(RenpuStepPos + 2, gate);
}
#endif
}
delta += putZvar(RenpuStepPos + delta, gateold);
trkinf[Trk].r->pflg = 0;
/*fprintf(stderr,"%d]\n",gateold); */
if (delta && delta < 4) {
/*const UBYTE *p = RenpuStepPos; */
/*fprintf(stderr,"[%.2X %.2X %.2X %.2X]",*(p + delta), *(p+delta+1), *(p+delta+2),*(p+delta+3));*/
/*fprintf(stderr,"(%.2X %.2X %.2X)",*(p+4), *(p+5), *(p+6)); */
memmove(RenpuStepPos + delta,
RenpuStepPos + 4,
trkdata[Trk].zmd - (RenpuStepPos + 4) );
ofst += (4 - delta);
/*fprintf(stderr,"(%.2X %.2X %.2X %.2X)",*(p + delta), *(p+delta+1), *(p+delta+2),*(p+delta+3)); */
}
if (lastchord) {
CHKCHORD *c = trkinf[Trk].c;
while (c->next != NULL) {
c->renputieflg = 0;
c = c->next;
}
c = trkinf[Trk].c;
while (c->next != NULL) {
if (c->note == note) { /* if there is tie-d tone before */
c->renputieflg = 1;
}
c = c->next;
}
c = trkinf[Trk].c;
while (c->next != NULL) {
if (c->renputieflg) { /* */
c->gatepos -= delta;
}
c = c->next;
}
}
}
trkinf[Trk].renpnotes = 0;
trkdata[Trk].zmd -= ofst;
}
return zms;
}
#ifdef A
void makePortBresemhamPara(WORD br,WORD *add,WORD *cor,UWORD step)
{
if (step) {
DWORD tempcor;
if (br < 0) {
br = -br;
*add = -(br / step);
} else {
*add = br / step;
}
tempcor = ((DWORD)br % step) * 256;
br = tempcor % step; /* br: temporary */
tempcor /= step;
if (br) {
tempcor++;
}
*cor = tempcor;
} else {
*add = *cor = 0;
}
}
#endif
void setVelocitySequenceMode(TRKINF *trkinf,const BYTE trk,int mode)
{
trkinf[trk].velou.relflg[0] = mode;
}
inline void recoverSpecialVelocity(TRKINF *trkinf, int Trk)
{
if (trkinf[Trk].spvelomode) {
trkinf[Trk].spvelomode = 0;
}
}
UBYTE *checkOctaveChange(UBYTE *zms,TRKINF *trkinf,const int Trk)
{
while (*zms == '<' || *zms == '>' || *zms == 'o' || *zms == 'O') {
switch (*zms++) {
case 'o':
case 'O':
{
DWORD tmpDWORD;
zms = get1AbsPara(zms,&tmpDWORD,-1,9,
"octave parameter is out of range(-1 - 9).",
"'o'(octave set) must be followed to its parameter.");
trkinf[Trk].octave = tmpDWORD;
}
break;
case '<':
trkinf[Trk].octave++;
break;
case '>':
trkinf[Trk].octave--;
break;
}
if (trkinf[Trk].octave < -1 || 9 < trkinf[Trk].octave) {
zmserror("octave parameter is out of range(-1 - 9).",line,linebuf,zms,0,1);
}
}
return zms;
}
void incrementStepCounters(TRKINF *trkinf, UWORD step)
{
if (!(trkinf->renpnotes)) {
trkinf->total += step;
/*
if (trkinf->s->prev) {
trkinf->s->step += step;
}
*/
}
}
int putZvar(UBYTE *zmd, DWORD var)
{
if (var < 128) {
*zmd = var;
return 1;
} else if (var == 0xFFFF || var == 0x8000) {
putWord(zmd, var);
return 2;
} else if (var > 0x8000) {
putWord(zmd, var);
return 2;
} else {
putWord(zmd, var + 0x8000);
return 2;
}
}
DWORD getZvar(UBYTE *zmd)
{
DWORD ret;
if (*zmd < 0x80) {
ret = *zmd;
} else if (*zmd == 0x80) {
ret = getWord(zmd);
} else {
ret = (*zmd - 0x80) * 0x100 + *(zmd + 1);
}
return ret;
}
int putStepGate(UBYTE *zmd, RENP *r, UWORD step, UWORD gate)
{
if (r) { /* always 2byte while renpu */
putWord(zmd, step);
putWord(zmd + 2, gate);
/* fprintf(stderr,"[%d / %d]\n",step,gate); */
return 4;
} else {
const UBYTE *zmd_ = zmd;
zmd += putZvar(zmd, step);
zmd += putZvar(zmd, gate);
return zmd - zmd_;
}
}
void freeAllChord(CHKCHORD *c)
{
if (c->next) {
CHKCHORD *c_org = c;
c = c->next;
do {
CHKCHORD *n = c->next;
efree(c,"c");
c = n;
} while (c != NULL);
c = c_org;
}
c->next = c->prev = NULL;
c->note = -1;
}
UBYTE *getChordGatePos(UBYTE *zmdbuf, DWORD gatepos, DWORD renpnotes)
{
UBYTE *CHORDGATEPOS;
CHORDGATEPOS = zmdbuf + gatepos + 1;
CHORDGATEPOS += (*CHORDGATEPOS >= 0x80 || renpnotes)? 2 : 1;
if (renpnotes && *(CHORDGATEPOS - 1) == 0x80 && *CHORDGATEPOS == 0x00) {
CHORDGATEPOS--;
}
return CHORDGATEPOS;
}